package com.ansion.commonchat.startup.workmanager.bwork;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.ansion.log.LogTag;
import com.ansion.log.VLog;

import java.lang.reflect.Constructor;


/**
 * Created by wanghongjie on 2023/5/11
 * Describe :  用于创建 Worker 实例，以便在工作请求中执行后台工作。
 * <p>
 * 通过实现该接口，您可以自定义 Worker 对象的创建过程，并在创建实例时进行自定义配置。
 */
public abstract class BWorkerFactory {

    public abstract @Nullable
    BListenableWorker createWorker(
            @NonNull Context appContext,
            @NonNull String workerClassName,
            @NonNull BWorkerParameters workerParameters);

    public final @Nullable
    BListenableWorker createWorkerWithDefaultFallback(
            @NonNull Context appContext,
            @NonNull String workerClassName,
            @NonNull BWorkerParameters workerParameters) {

        BListenableWorker worker = createWorker(appContext, workerClassName, workerParameters);
        if (worker == null) {
            Class<? extends BListenableWorker> clazz = null;
            try {
                clazz = Class.forName(workerClassName).asSubclass(BListenableWorker.class);
            } catch (Throwable throwable) {
                if (VLog.OPEN_LOG)
                    VLog.e(LogTag.TAG_B_WORK_MANAGER, "Invalid class:  %s , throwable : %s ", workerClassName, throwable.getMessage());
            }
            if (clazz != null) {
                try {
                    Constructor<? extends BListenableWorker> constructor =
                            clazz.getDeclaredConstructor(Context.class, BWorkerParameters.class);
                    worker = constructor.newInstance(
                            appContext,
                            workerParameters);
                } catch (Throwable e) {
                    if (VLog.OPEN_LOG)
                        VLog.e(LogTag.TAG_B_WORK_MANAGER, "Could not instantiate : %s , Throwable : %s", workerClassName, e.getMessage());
                }
            }
        }

        if (worker != null && worker.isUsed()) {
            String factoryName = this.getClass().getName();
            String message = String.format("BWorkerFactory (%s) returned an instance of a "
                            + "ListenableWorker (%s) which has already been invoked. "
                            + "createWorker() must always return a new instance of a "
                            + "ListenableWorker.",
                    factoryName, workerClassName);

            throw new IllegalStateException(message);
        }

        return worker;
    }

    public static @NonNull
    BWorkerFactory getDefaultWorkerFactory() {
        return new BWorkerFactory() {
            @Override
            public @Nullable
            BListenableWorker createWorker(
                    @NonNull Context appContext,
                    @NonNull String workerClassName,
                    @NonNull BWorkerParameters workerParameters) {
                return null;
            }
        };
    }
}